home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-portable.exe / quodlibet-3.3.0-portable / data / bin / quodlibet / qltk / notif.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  13KB  |  339 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. '''
  5. This module will provide a unified notification area for informational
  6. messages and active tasks. This will eventually handle interactions with
  7. active tasks (e.g. pausing a copooled task), and provide shortcuts for
  8. copooling or threading a task with a status notification. It will also provide
  9. the UI for the planned global undo feature.
  10.  
  11. Of course, right now it does none of these things.
  12. '''
  13. from gi.repository import Gtk, GLib, Pango
  14. from quodlibet.util import copool
  15. from quodlibet.qltk.x import SmallImageToggleButton, SmallImageButton
  16. SIZE = Gtk.IconSize.MENU
  17.  
  18. class ParentProperty(object):
  19.     """
  20.     A property which provides a thin layer of protection against accidental
  21.     reparenting: you must first 'unparent' an instance by setting this
  22.     property to 'None' before you can set a new parent.
  23.     """
  24.     
  25.     def __get__(self, inst, owner):
  26.         return getattr(inst, '_parent', None)
  27.  
  28.     
  29.     def __set__(self, inst, value):
  30.         if getattr(inst, '_parent', None) is not None and value is not None:
  31.             raise ValueError("Cannot set parent property without first setting it to 'None'.")
  32.         inst._parent = value
  33.  
  34.  
  35.  
  36. class Task(object):
  37.     
  38.     def __init__(self, source, desc, known_length = True, controller = None, pause = None, stop = None):
  39.         self.source = source
  40.         self.desc = desc
  41.         if known_length:
  42.             self.frac = 0
  43.         else:
  44.             self.frac = None
  45.         if controller:
  46.             self.controller = controller
  47.         else:
  48.             self.controller = TaskController.default_instance
  49.         self._pause = pause
  50.         self._stop = stop
  51.         self.pausable = bool(pause)
  52.         self.stoppable = bool(stop)
  53.         self._paused = False
  54.         self.controller.add_task(self)
  55.  
  56.     
  57.     def update(self, frac):
  58.         """
  59.         Update a task's progress.
  60.         """
  61.         self.frac = frac
  62.         self.controller.update()
  63.  
  64.     
  65.     def pulse(self):
  66.         '''
  67.         Indicate progress on a task of unknown length.
  68.         '''
  69.         self.update(None)
  70.  
  71.     
  72.     def finish(self):
  73.         '''
  74.         Mark a task as finished, and remove it from the list of active tasks.
  75.         '''
  76.         self.frac = 1
  77.         self.controller.finish(self)
  78.  
  79.     
  80.     def __set_paused(self, value):
  81.         if self.pausable:
  82.             self._pause(value)
  83.             self._paused = value
  84.  
  85.     paused = property((lambda self: self._paused), __set_paused)
  86.     
  87.     def stop(self):
  88.         if self._stop:
  89.             self._stop()
  90.         self.finish()
  91.  
  92.     
  93.     def gen(self, gen):
  94.         """
  95.         Act as a generator pass-through, updating and finishing the task's
  96.         progress automatically. If 'gen' has a __len__ property, it will be
  97.         used to set the fraction accordingly.
  98.         """
  99.         
  100.         try:
  101.             if hasattr(gen, '__len__'):
  102.                 for i, x in enumerate(gen):
  103.                     self.update(float(i) / len(gen))
  104.                     yield x
  105.                 
  106.             else:
  107.                 for x in gen:
  108.                     yield x
  109.                 self.finish()
  110.                 return None
  111.  
  112.  
  113.     
  114.     def list(self, l):
  115.         """
  116.         Evaluates the iterable argument before passing to 'gen'.
  117.         """
  118.         return self.gen(list(l))
  119.  
  120.     
  121.     def copool(self, funcid, pause = True, stop = True):
  122.         """
  123.         Convenience function: set the Task's 'pause' and 'stop' callbacks to
  124.         act upon the copool with the given funcid.
  125.         """
  126.         if pause:
  127.             
  128.             def pause_func(state):
  129.                 if state != self._paused:
  130.                     if state:
  131.                         copool.pause(funcid)
  132.                     else:
  133.                         copool.resume(funcid)
  134.  
  135.             self._pause = pause_func
  136.             self.pausable = True
  137.         if stop:
  138.             
  139.             self._stop = lambda : copool.remove(funcid)
  140.             self.stoppable = True
  141.  
  142.     
  143.     def __enter__(self):
  144.         return self
  145.  
  146.     
  147.     def __exit__(self, exc_type, exc_val, exc_tb):
  148.         self.finish()
  149.         return False
  150.  
  151.  
  152.  
  153. class TaskController(object):
  154.     '''
  155.     Controller logic for displaying and managing a list of Tasks. Also
  156.     implements the full Task interface to act as a pass-through or summary of
  157.     all tasks in flight on this controller.
  158.     '''
  159.     parent = ParentProperty()
  160.     default_instance = None
  161.     
  162.     def __init__(self):
  163.         self.active_tasks = []
  164.         self._parent = None
  165.         self.update()
  166.  
  167.     
  168.     def add_task(self, task):
  169.         self.active_tasks.append(task)
  170.         self.update()
  171.  
  172.     
  173.     def source(self):
  174.         if len(self.active_tasks) == 1:
  175.             return self.active_tasks[0].source
  176.         return None('Active tasks')
  177.  
  178.     source = property(source)
  179.     
  180.     def desc(self):
  181.         if len(self.active_tasks) == 1:
  182.             return self.active_tasks[0].desc
  183.         return None('%d tasks running') % len(self.active_tasks)
  184.  
  185.     desc = property(desc)
  186.     
  187.     def frac(self):
  188.         fracs = [ t.frac for t in self.active_tasks if t.frac is not None ]
  189.         if fracs:
  190.             return sum(fracs) / len(self.active_tasks)
  191.  
  192.     frac = property(frac)
  193.     
  194.     def __set_paused(self, val):
  195.         for t in self.active_tasks:
  196.             if t.pausable:
  197.                 t.paused = val
  198.                 continue
  199.  
  200.     
  201.     def __get_paused(self):
  202.         pausable = [ t for t in self.active_tasks if t.pausable ]
  203.         if not pausable:
  204.             return False
  205.         return not [ t for t in pausable if t.paused ]
  206.  
  207.     paused = property(__get_paused, __set_paused)
  208.     
  209.     def stop(self):
  210.         [ t.stop() for t in self.active_tasks if t.stoppable ]
  211.  
  212.     
  213.     def pausable(self):
  214.         return [ t for t in self.active_tasks if t.pausable ]
  215.  
  216.     pausable = property(pausable)
  217.     
  218.     def stoppable(self):
  219.         return [ t for t in self.active_tasks if t.stoppable ]
  220.  
  221.     stoppable = property(stoppable)
  222.     
  223.     def update(self):
  224.         if self._parent is not None:
  225.             self._parent.update()
  226.  
  227.     
  228.     def finish(self, finished_task):
  229.         self.active_tasks = (filter,)((lambda t: t is not finished_task), self.active_tasks)
  230.         self.update()
  231.  
  232.  
  233. TaskController.default_instance = TaskController()
  234.  
  235. class TaskWidget(Gtk.HBox):
  236.     '''
  237.     Displays a task.
  238.     '''
  239.     
  240.     def __init__(self, task):
  241.         super(TaskWidget, self).__init__(spacing = 2)
  242.         self.task = task
  243.         self.label = Gtk.Label()
  244.         self.label.set_alignment(1, 0.5)
  245.         self.label.set_ellipsize(Pango.EllipsizeMode.END)
  246.         self.pack_start(self.label, True, True, 12)
  247.         self.progress = Gtk.ProgressBar()
  248.         self.progress.set_size_request(100, -1)
  249.         self.pack_start(self.progress, True, True, 0)
  250.         self.pause = SmallImageToggleButton()
  251.         self.pause.add(Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE, SIZE))
  252.         self.pause.connect('toggled', self._TaskWidget__pause_toggled)
  253.         self.pack_start(self.pause, False, True, 0)
  254.         self.stop = SmallImageButton()
  255.         self.stop.add(Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_STOP, SIZE))
  256.         self.stop.connect('clicked', self._TaskWidget__stop_clicked)
  257.         self.pack_start(self.stop, False, True, 0)
  258.  
  259.     
  260.     def __pause_toggled(self, btn):
  261.         if self.task.pausable:
  262.             self.task.paused = btn.props.active
  263.  
  264.     
  265.     def __stop_clicked(self, btn):
  266.         if self.task.stoppable:
  267.             self.task.stop()
  268.  
  269.     
  270.     def update(self):
  271.         formatted_label = '<small><b>%s</b>\n%s</small>' % (self.task.source, self.task.desc)
  272.         self.label.set_markup(formatted_label)
  273.         if self.task.frac is not None:
  274.             self.progress.set_fraction(self.task.frac)
  275.         else:
  276.             self.progress.pulse()
  277.         show_as_active = None if self.pause.props.sensitive != self.task.pausable else self.task.paused
  278.         if self.pause.props.active != show_as_active:
  279.             self.pause.props.active = show_as_active
  280.         if self.stop.props.sensitive != self.task.stoppable:
  281.             self.stop.props.sensitive = self.task.stoppable
  282.  
  283.  
  284.  
  285. class StatusBar(Gtk.HBox):
  286.     
  287.     def __init__(self, task_controller):
  288.         super(StatusBar, self).__init__()
  289.         self._StatusBar__dirty = False
  290.         self.set_spacing(12)
  291.         self.task_controller = task_controller
  292.         self.task_controller.parent = self
  293.         self.default_label = Gtk.Label(selectable = True)
  294.         self.default_label.set_text(_('No time information'))
  295.         self.default_label.set_ellipsize(Pango.EllipsizeMode.END)
  296.         self.pack_start(Gtk.Alignment(xalign = 1, xscale = 0, child = self.default_label), True, True, 0)
  297.         self.task_widget = TaskWidget(task_controller)
  298.         self.pack_start(self.task_widget, True, True, 0)
  299.         self.show_all()
  300.         self.set_no_show_all(True)
  301.         self._StatusBar__set_shown('default')
  302.         self.connect('destroy', self._StatusBar__destroy)
  303.  
  304.     
  305.     def __destroy(self, *args):
  306.         self.task_controller.parent = None
  307.  
  308.     
  309.     def __set_shown(self, type):
  310.         if type == 'default':
  311.             self.default_label.show()
  312.         else:
  313.             self.default_label.hide()
  314.         if type == 'task':
  315.             self.task_widget.show()
  316.         else:
  317.             self.task_widget.hide()
  318.  
  319.     
  320.     def set_default_text(self, text):
  321.         self.default_label.set_text(text)
  322.  
  323.     
  324.     def __update(self):
  325.         self._StatusBar__dirty = False
  326.         if self.task_controller.active_tasks:
  327.             self._StatusBar__set_shown('task')
  328.             self.task_widget.update()
  329.         else:
  330.             self._StatusBar__set_shown('default')
  331.  
  332.     
  333.     def update(self):
  334.         if not self._StatusBar__dirty:
  335.             self._StatusBar__dirty = True
  336.             GLib.idle_add(self._StatusBar__update)
  337.  
  338.  
  339.